﻿using System;
#if SILVERLIGHT
using System.Windows;
using System.Windows.Data;
using System.Globalization;
#else
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
#endif

namespace Microsoft.PlayerFramework
{
    /// <summary>
    /// An enum indicating a specific unit of Time.
    /// </summary>
    public enum TimeUnit
    {
        /// <summary>
        /// Total days unit
        /// </summary>
        Days,
        /// <summary>
        /// Total hours unit
        /// </summary>
        Hours,
        /// <summary>
        /// Total minutes unit
        /// </summary>
        Minutes,
        /// <summary>
        /// Total seconds unit
        /// </summary>
        Seconds,
        /// <summary>
        /// Total milliseconds unit
        /// </summary>
        Milliseconds
    }

    /// <summary>
    /// IValueConverter used to help Xaml bind a TimeSpan to an double by pulling out a specific unit of the TimeSpan.
    /// For example, 00:01:10 could be converted to 70 if TimeUnit == Seconds.
    /// </summary>
    public class TimeUnitConverter : IValueConverter
    {
        /// <summary>
        /// Instantiates a new instance of the TimeSpanPartConverter class, defaulting the TimeUnit to Seconds.
        /// </summary>
        public TimeUnitConverter() 
        {
            TimeUnit = TimeUnit.Seconds;
        }

        /// <summary>
        /// Instantiates a new instance of the TimeSpanPartConverter class.
        /// </summary>
        /// <param name="timeSpanPart">Enum indicating which unit of time to convert to.</param>
        public TimeUnitConverter(TimeUnit timeSpanPart)
        {
            this.TimeUnit = timeSpanPart;
        }

        /// <summary>
        /// The unit of the TimeSpan that should be used during conversion.
        /// </summary>
        public TimeUnit TimeUnit { get; set; }

        /// <summary>
        /// Converts the TimeSpan to an double.
        /// </summary>
        /// <param name="value">The TimeSpan to convert</param>
        /// <param name="timeUnit">The unit of the TimeSpan to use.</param>
        /// <returns>A double representing the total time of the TimeSpan.</returns>
        public static double Convert(TimeSpan value, TimeUnit timeUnit)
        {
            switch (timeUnit)
            {
                case TimeUnit.Seconds:
                    return value.TotalSeconds;
                case TimeUnit.Days:
                    return value.TotalDays;
                case TimeUnit.Hours:
                    return value.TotalHours;
                case TimeUnit.Milliseconds:
                    return value.TotalMilliseconds;
                case TimeUnit.Minutes:
                    return value.TotalMinutes;
            }
            return 0;
        }

        /// <summary>
        /// Converts a double to a TimeSpan.
        /// </summary>
        /// <param name="value">The value in the specified units to convert.</param>
        /// <param name="timeUnit">The unit to use when converting the number to a TimeSpan.</param>
        /// <returns>A TimeSpan that represents the given time.</returns>
        public static TimeSpan ConvertBack(double value, TimeUnit timeUnit)
        {
            switch (timeUnit)
            {
                case TimeUnit.Seconds:
                    return TimeSpan.FromSeconds(value);
                case TimeUnit.Days:
                    return TimeSpan.FromDays(value);
                case TimeUnit.Hours:
                    return TimeSpan.FromHours(value);
                case TimeUnit.Milliseconds:
                    return TimeSpan.FromMilliseconds(value);
                case TimeUnit.Minutes:
                    return TimeSpan.FromMinutes(value);
            }
            return TimeSpan.Zero;
        }

        /// <inheritdoc /> 
#if SILVERLIGHT
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
#else
        public object Convert(object value, Type targetType, object parameter, string culture)
#endif
        {
            return Convert((TimeSpan)value, TimeUnit);
        }

        /// <inheritdoc /> 
#if SILVERLIGHT
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
#else
        public object ConvertBack(object value, Type targetType, object parameter, string culture)
#endif
        {
            return ConvertBack((double)value, TimeUnit);
        }
    }
}
